package xiaye.mycrawler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.google.inject.Inject;
import com.google.inject.Provider;

public class SimpleCrawler implements Crawler {
	private static final int MAX_THREAD = 10;
	private Frontier frontier;
	private PageStore store;
	private ThreadPoolExecutor executor = 
				new ThreadPoolExecutor(MAX_THREAD, MAX_THREAD, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
	private Provider<CrawlerThread> threadProvider;
	
	@Inject
	public SimpleCrawler(Frontier frontier, PageStore store,
			Provider<CrawlerThread> threadProvider){
		this.frontier = frontier;
		this.store = store;
		this.threadProvider = threadProvider;
	}
	
	public void start(){
		try{
			while (true){
				schedule();
			}
		}catch (FrontierEmptyException e){
			e.printStackTrace();
		}
	}
	
	private void schedule() throws FrontierEmptyException{
		while (true){
			if (queueingThreadTooFew()){
				enqueueNextAddress();
			}else{
				break;
			}
		}
		waitAMoment();
	}

	private boolean queueingThreadTooFew() {
		if (executor.getQueue().size() < 5){
			return true;
		}
		return false;
	}

	private void enqueueNextAddress() throws FrontierEmptyException {
		Address next = frontier.getNext();
		CrawlerThread thread = threadProvider.get();
		thread.setAddress(next);
		executor.execute(thread);
		System.out.println("scheduling url: "+ next);
	}

	private void waitAMoment() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}